#include <cassert>
#include <ctime>
#include <fstream>

#include "WLogInterface.h"
#include "Common.h"

namespace WLog
{
#ifdef WLOG_DEFAULT_XMLOUTER_FILE
	ILogProcess* log = new ILogProcess(new XmlOuter(new std::ofstream(buildFileNameNow("", ".xml").c_str())));
#elif  WLOG_DEFAULT_XMLOUTER
	ILogProcess* log = new ILogProcess(new XmlOuter(&std::cout));
#elif  WLOG_DEFAULT_BLOCKOUTER_FILE
	ILogProcess* log = new ILogProcess(new BlockOuter(new std::ofstream(buildFileNameNow().c_str())));
#elif  WLOG_DEFAULT_BLOCKOUTER
	ILogProcess* log = new ILogProcess(new BlockOuter(&std::cout));
#elif  WLOG_DEFAULT_REGULAROUTER_FILE
	ILogProcess* log = new ILogProcess(new RegularOuter(new std::ofstream(buildFileNameNow().c_str())));
#elif  WLOG_DEFAULT_REGULAROUTER
	ILogProcess* log = new ILogProcess(new RegularOuter(&std::cout));
#else
	ILogProcess* log = new ILogProcess;
#endif // WLOG_DEFAULT_XML    

	ILogProcess* setLog(ILogProcess* pLog)
	{
		ILogProcess* pBak = log;
		log = pLog;
		return pBak;
	}

	ILogProcess* getLog()
	{
		return log;
	}	
	
	void autoDelLog(bool bDelLog/* = true*/, bool bDelOuter/* = true*/, bool bDelOstream/* = true*/)
	{
		if (!getLog())
		{
			return;
		}
		std::ostream *pOs = getLog()->getOuter()->getOstream();
				
		if (bDelOuter)
		{
			if (getLog()->getOuter())
			{
				delete getLog()->setOuter(0);
			}
		}
		
		if (bDelOstream)
		{			
			if (pOs && *pOs != std::cout && *pOs != std::cerr)
			{
				delete pOs;
			}
		}

		if (bDelLog)
		{
			delete setLog(0);
		}
	}

    string buildFileNameNow(const char* szPrefix /*= ""*/, const char* szEnd /*= ".log"*/, const char* szFormatDateTime /*= "%Y-%m-%d_%H%M%S"*/)
    {
#define _TIME_MAX_BUF_SIZE 256
        char* pBuf = new char[_TIME_MAX_BUF_SIZE];
        time_t time = now_time_t();
#ifdef MORE_AND_EQUAL_THAN_VC8_VS2005
        tm timeinfo = {0};
        localtime_s(&timeinfo, &time);
        tm* tLocalTime = &timeinfo;
#else
        tm* tLocalTime = localtime(&time);
#endif // MORE_AND_EQUAL_THAN_VC8_VS2005

        strftime(pBuf, _TIME_MAX_BUF_SIZE, szFormatDateTime, tLocalTime);
        
        string strRet = szPrefix;
        strRet += pBuf;
        strRet += szEnd;
        delete [] pBuf;
        
        return strRet;
    }

	void setLog_File_Xml(std::string strFileName/* = buildFileNameNow("", ".xml")*/)
	{
		autoDelLog();

		log = new ILogProcess(new XmlOuter(new std::ofstream(strFileName.c_str())));		
	}

	void setLog_Ostream_Xml(std::ostream *pOs/* = &std::cout*/)
	{
		autoDelLog();
		log = new ILogProcess(new XmlOuter(pOs));	
	}

	void setLog_File_Block(std::string strFileName/* = buildFileNameNow("block")*/)
	{
		autoDelLog();
		log = new ILogProcess(new BlockOuter(new std::ofstream(strFileName.c_str())));
	}

	void setLog_Ostream_Block(std::ostream *pOs/* = &std::cout*/)
	{
		autoDelLog();
		log = new ILogProcess(new BlockOuter(pOs));
	}

	void setLog_File_Regular(std::string strFileName/* = buildFileNameNow("regular")*/)
	{
		autoDelLog();
		log = new ILogProcess(new RegularOuter(new std::ofstream(strFileName.c_str())));
	}

	void setLog_Ostream_Regular(std::ostream *pOs/* = &std::cout*/)
	{
		autoDelLog();
		log = new ILogProcess(new RegularOuter(pOs));
	}
}
